package ccm.tools;

public class GenerateColor
{
    private static double[] RGB2LAB(int R,int G,int B)
    {
        double RR=gamma(R/255.0);
        double GG=gamma(G/255.0);
        double BB=gamma(B/255.0);
        double X=0.4124564f*RR+0.3575761f*GG+0.1804375f*BB;
        double Y=0.2126729f*RR+0.7151522f*GG+0.0721750f*BB;
        double Z=0.0193339f*RR+0.1191920f*GG+0.9503041f*BB;

        double fX, fY, fZ;

        X/=(0.950456);
        Y/=(1.0);
        Z/=(1.088754);

        if(Y>0.008856f)
            fY=Math.pow(Y,1.0/3.0);
        else
            fY=7.787f*Y+16.0/116.0;

        if(X>0.008856f)
            fX=Math.pow(X,1.0/3.0);
        else
            fX=7.787f*X+16.0/116.0;

        if(Z>0.008856)
            fZ=Math.pow(Z,1.0/3.0);
        else
            fZ=7.787f*Z+16.0/116.0;

        double[] out=new double[3];
        out[0]=116.0f*fY-16.0f;
        out[0]=out[0]>0.0f?out[0]:0.0f;
        out[1]=500.0f*(fX-fY);
        out[2]=200.0f*(fY-fZ);
        return out;
    }

    private static double gamma(double x)
    {
        return x>0.04045?Math.pow((x+0.055f)/1.055f,2.4f):(x/12.92);
    }

    public static double deltaE2000(double[] A,double[] B)
    {
        return deltaE2000(A[0],A[1],A[2],B[0],B[1],B[2]);
    }

    public static double deltaE2000(double L1,double a1,double b1,double L2,double a2,double b2)
    {
        //参考《现代颜色技术原理及应用》P88数据
        double E00=0;               //CIEDE2000色差E00
        double LL1, LL2, aa1, aa2, bb1, bb2; //声明L' a' b' （1,2）
        double delta_LL, delta_CC, delta_hh, delta_HH;        // 第二部的四个量
        double kL, kC, kH;
        double RT=0;                //旋转函数RT
        double G=0;                  //G表示CIELab 颜色空间a轴的调整因子,是彩度的函数.
        double mean_Cab=0;    //两个样品彩度的算术平均值
        double SL, SC, SH, T;
        //------------------------------------------
        //参考实验条件见P88
        kL=1;
        kC=1;
        kH=1;
        //------------------------------------------
        mean_Cab=(CaiDu(a1,b1)+CaiDu(a2,b2))/2;
        double mean_Cab_pow7=Math.pow(mean_Cab,7);       //两彩度平均值的7次方
        G=0.5*(1-Math.pow(mean_Cab_pow7/(mean_Cab_pow7+Math.pow(25,7)),0.5));

        LL1=L1;
        aa1=a1*(1+G);
        bb1=b1;

        LL2=L2;
        aa2=a2*(1+G);
        bb2=b2;

        double CC1, CC2;               //两样本的彩度值
        CC1=CaiDu(aa1,bb1);
        CC2=CaiDu(aa2,bb2);
        double hh1, hh2;                  //两样本的色调角
        hh1=SeDiaoJiao(aa1,bb1);
        hh2=SeDiaoJiao(aa2,bb2);

        delta_LL=LL1-LL2;
        delta_CC=CC1-CC2;
        delta_hh=SeDiaoJiao(aa1,bb1)-SeDiaoJiao(aa2,bb2);
        delta_HH=2*Math.sin(Math.PI*delta_hh/360)*Math.pow(CC1*CC2,0.5);

        //-------第三步--------------
        //计算公式中的加权函数SL,SC,SH,T
        double mean_LL=(LL1+LL2)/2;
        double mean_CC=(CC1+CC2)/2;
        double mean_hh=(hh1+hh2)/2;

        SL=1+0.015*Math.pow(mean_LL-50,2)/Math.pow(20+Math.pow(mean_LL-50,2),0.5);
        SC=1+0.045*mean_CC;
        T =1-0.17*Math.cos((mean_hh-30)*Math.PI/180)+0.24*Math.cos((2*mean_hh)*Math.PI/180)+0.32*Math.cos((3*mean_hh+6)*Math.PI/180)-0.2*Math.cos((4*mean_hh-63)*Math.PI/180);
        SH=1+0.015*mean_CC*T;

        //------第四步--------
        //计算公式中的RT
        double mean_CC_pow7=Math.pow(mean_CC,7);
        double RC=2*Math.pow(mean_CC_pow7/(mean_CC_pow7+Math.pow(25,7)),0.5);
        double delta_xita=30*Math.exp(-Math.pow((mean_hh-275)/25,2));        //△θ 以°为单位
        RT=-Math.sin((2*delta_xita)*Math.PI/180)*RC;

        double L_item, C_item, H_item;
        L_item=delta_LL/(kL*SL);
        C_item=delta_CC/(kC*SC);
        H_item=delta_HH/(kH*SH);

        E00=Math.pow(L_item*L_item+C_item*C_item+H_item*H_item+RT*C_item*H_item,0.5);

        return E00;
    }

    //彩度计算
    private static double CaiDu(double a,double b)
    {
        double Cab=0;
        Cab=Math.pow(a*a+b*b,0.5);
        return Cab;
    }

    //色调角计算
    private static double SeDiaoJiao(double a,double b)
    {
        double h=0;
        double hab=0;

        h=(180/Math.PI)*Math.atan(b/a);           //有正有负

        if(a>0&&b>0)
        {
            hab=h;
        }
        else if(a<0&&b>0)
        {
            hab=180+h;
        }
        else if(a<0&&b<0)
        {
            hab=180+h;
        }
        else     //a>0&&b<0
        {
            hab=360+h;
        }
        return hab;
    }

    public static void main(String[] args)
    {
        // int   N  =256;
        // int[] R  =new int[N];
        // int[] G  =new int[N];
        // int[] B  =new int[N];
        // int   cnt=0;
        // for(int r=10;r<255&&cnt<N;++r)
        // for(int g=10;g<255&&cnt<N;++g)
        // for(int b=10;b<255&&cnt<N;++b)
        // {
        // boolean flag=true;
        // for(int i=0;flag&&i<cnt;++i)
        // flag=deltaE2000(RGB2LAB(r,g,b),RGB2LAB(R[i],G[i],B[i]))>=10;
        // if(flag)
        // {
        // R[cnt]=r;
        // G[cnt]=g;
        // B[cnt]=b;
        // ++cnt;
        // System.out.println(cnt+" RGB:"+r+","+g+","+b);
        // }
        // }
        String[] str={
                "ed1299",
                "09f9f5",
                "246b93",
                "cc8e12",
                "d561dd",
                "c93f00",
                "ddd53e",
                "4aef7b",
                "e86502",
                "9ed84e",
                "39ba30",
                "6ad157",
                "8249aa",
                "99db27",
                "e07233",
                "ff523f",
                "ce2523",
                "f7aa5d",
                "cebb10",
                "03827f",
                "931635",
                "373bbf",
                "a1ce4c",
                "ef3bb6",
                "d66551",
                "1a918f",
                "ff66fc",
                "2927c4",
                "7149af",
                "57e559",
                "8e3af4",
                "f9a270",
                "22547f",
                "db5e92",
                "edd05e",
                "6f25e8",
                "0dbc21",
                "280f7a",
                "6373ed",
                "5b910f",
                "7b34c1",
                "0cf29a",
                "d80fc1",
                "dd27ce",
                "07a301",
                "167275",
                "391c82",
                "2baeb5",
                "925bea",
                "63ff4f"
        };
        for(String s: str)
        {
            int R, G, B;
            int a=Integer.parseInt(s,16);
            int r=(a>>16)&0XFF;
            int g=(a>>8)&0XFF;
            int b=(a)&0XFF;
            // int rgb=((0x001f&((r) >> 3))<<11)|(((0x003f)&((g) >> 2))<<5)|(0x001f&((b) >> 3));
            // System.out.println(String.format("0X%04X,",rgb));
            System.out.println(String.format("{0X%02X,0X%02X,0X%02X},",r,g,b));
        }

    }
}
